1 /// Credit Simie
2 ///
Sourced from - http://forum.unity3d.com/threads/flowlayoutgroup.296709/
3 ///
Example http://forum.unity3d.com/threads/flowlayoutgroup.296709/
4 ///
Update by Martin Sharkbomb - http://forum.unity3d.com/threads/flowlayoutgroup.296709/#post-1977028
5 ///
Last item alignment fix by Vicente Russo - https://bitbucket.org/ddreaper/unity-ui-extensions/issues/22/flow-layout-group-align
6
7 using
System.Collections.Generic;
8
9 namespace
UnityEngine.UI.Extensions
10 {

11     ///
<summary>
12     ///
Layout Group controller that arranges children in rows, fitting as many on a line until total width exceeds parent bounds
13     ///
</summary>
14     
[AddComponentMenu("Layout/Extensions/Flow Layout Group")]
15     
public class FlowLayoutGroup : LayoutGroup
16     {
17         
public float SpacingX = 0f;
18         
public float SpacingY = 0f;
19         
public bool ExpandHorizontalSpacing = false;
20         
21         
public bool ChildForceExpandWidth = false;
22         
public bool ChildForceExpandHeight = false;
23         
24         
private float _layoutHeight;
25         
26         
public override void CalculateLayoutInputHorizontal()
27         {
28             
29             
base.CalculateLayoutInputHorizontal();
30             
31             
var minWidth = GetGreatestMinimumChildWidth() + padding.left + padding.right;
32             
33             SetLayoutInputForAxis(minWidth, -
1, -1, 0);
34             
35         }
36         
37         
public override void SetLayoutHorizontal()
38         {
39             SetLayout(rectTransform.rect.width,
0, false);
40         }
41         
42         
public override void SetLayoutVertical()
43         {
44             SetLayout(rectTransform.rect.width,
1, false);
45         }
46         
47         
public override void CalculateLayoutInputVertical()
48         {
49             _layoutHeight = SetLayout(rectTransform.rect.width,
1, true);
50         }
51         
52         
protected bool IsCenterAlign
53         {
54             
get
55             {
56                 
return childAlignment == TextAnchor.LowerCenter || childAlignment == TextAnchor.MiddleCenter ||
57                     childAlignment == TextAnchor.UpperCenter;
58             }
59         }
60         
61         
protected bool IsRightAlign
62         {
63             
get
64             {
65                 
return childAlignment == TextAnchor.LowerRight || childAlignment == TextAnchor.MiddleRight ||
66                     childAlignment == TextAnchor.UpperRight;
67             }
68         }
69         
70         
protected bool IsMiddleAlign
71         {
72             
get
73             {
74                 
return childAlignment == TextAnchor.MiddleLeft || childAlignment == TextAnchor.MiddleRight ||
75                     childAlignment == TextAnchor.MiddleCenter;
76             }
77         }
78         
79         
protected bool IsLowerAlign
80         {
81             
get
82             {
83                 
return childAlignment == TextAnchor.LowerLeft || childAlignment == TextAnchor.LowerRight ||
84                     childAlignment == TextAnchor.LowerCenter;
85             }
86         }

87         
88         ///
<summary>
89         ///
Holds the rects that will make up the current row being processed
90         ///
</summary>
91         
private readonly IList<RectTransform> _rowList = new List<RectTransform>();
92         
93         ///
<summary>
94         ///
Main layout method
95         ///
</summary>
96         ///
<param name="width">Width to calculate the layout with</param>
97         ///
<param name="axis">0 for horizontal axis, 1 for vertical</param>
98         ///
<param name="layoutInput">If true, sets the layout input for the axis. If false, sets child position for axis</param>
99         
public float SetLayout(float width, int axis, bool layoutInput)
100         {
101             
var groupHeight = rectTransform.rect.height;
102             
103             
// Width that is available after padding is subtracted
104             
var workingWidth = rectTransform.rect.width - padding.left - padding.right;
105             
106             
// Accumulates the total height of the rows, including spacing and padding.
107             
var yOffset = IsLowerAlign ? (float)padding.bottom : (float)padding.top;
108             
109             
var currentRowWidth = 0f;
110             
var currentRowHeight = 0f;
111             
112             
for (var i = 0; i < rectChildren.Count; i++) {
113                 
114                 
// LowerAlign works from back to front
115                 
var index = IsLowerAlign ? rectChildren.Count - 1 - i : i;
116                 
117                 
var child = rectChildren[index];
118                 
119                 
var childWidth = LayoutUtility.GetPreferredSize(child, 0);
120                 
var childHeight = LayoutUtility.GetPreferredSize(child, 1);
121                 
122                 
// Max child width is layout group width - padding
123                 childWidth = Mathf.Min(childWidth, workingWidth);
124                 
125                 
// If adding this element would exceed the bounds of the row,
126                 
// go to a new line after processing the current row
127                 
if (currentRowWidth + childWidth > workingWidth) {
128                     
129                     currentRowWidth -= SpacingX;
130                     
131                     
// Process current row elements positioning
132                     
if (!layoutInput) {
133                         
134                         
var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
135                         LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth, padding.left, h, axis);
136                         
137                     }
138                     
139                     
// Clear existing row
140                     _rowList.Clear();
141                     
142                     
// Add the current row height to total height accumulator, and reset to 0 for the next row
143                     yOffset += currentRowHeight;
144                     yOffset += SpacingY;
145                     
146                     currentRowHeight =
0;
147                     currentRowWidth =
0;
148                     
149                 }
150                 
151                 currentRowWidth += childWidth;
152                 _rowList.Add(child);
153                 
154                 
// We need the largest element height to determine the starting position of the next line
155                 
if (childHeight > currentRowHeight) {
156                     currentRowHeight = childHeight;
157                 }
158
159                 
// Don't do this for the last one
160                 
if (i < rectChildren.Count - 1 )
161                     currentRowWidth += SpacingX;
162             }
163             
164             
if (!layoutInput) {
165                 
var h = CalculateRowVerticalOffset(groupHeight, yOffset, currentRowHeight);
166                 currentRowWidth -= SpacingX;
167                 
// Layout the final row
168                 LayoutRow(_rowList, currentRowWidth, currentRowHeight, workingWidth - (_rowList.Count >
1 ? SpacingX : 0), padding.left, h, axis);
169             }
170             
171             _rowList.Clear();
172             
173             
// Add the last rows height to the height accumulator
174             yOffset += currentRowHeight;
175             yOffset += IsLowerAlign ? padding.top : padding.bottom;
176             
177             
if (layoutInput) {
178                 
179                 
if(axis == 1)
180                     SetLayoutInputForAxis(yOffset, yOffset, -
1, axis);
181                 
182             }
183             
184             
return yOffset;
185         }
186         
187         
private float CalculateRowVerticalOffset(float groupHeight, float yOffset, float currentRowHeight)
188         {
189             
float h;
190             
191             
if (IsLowerAlign) {
192                 h = groupHeight - yOffset - currentRowHeight;
193             }
else if (IsMiddleAlign) {
194                 h = groupHeight*
0.5f - _layoutHeight * 0.5f + yOffset;
195             }
else {
196                 h = yOffset;
197             }
198             
return h;
199         }
200         
201         
protected void LayoutRow(IList<RectTransform> contents, float rowWidth, float rowHeight, float maxWidth, float xOffset, float yOffset, int axis)
202         {
203             
var xPos = xOffset;
204             
205             
if (!ChildForceExpandWidth && IsCenterAlign)
206                 xPos += (maxWidth - rowWidth) *
0.5f;
207             
else if (!ChildForceExpandWidth && IsRightAlign)
208                 xPos += (maxWidth - rowWidth);
209             
210             
var extraWidth = 0f;
211             
var extraSpacing = 0f;
212
213             
if (ChildForceExpandWidth) {
214                 extraWidth = (maxWidth - rowWidth)/_rowList.Count;
215             }
216             
else if (ExpandHorizontalSpacing) {
217                 extraSpacing = (maxWidth - rowWidth)/(_rowList.Count -
1);
218                 
if (_rowList.Count > 1) {
219                     
if (IsCenterAlign)
220                         xPos -= extraSpacing *
0.5f * (_rowList.Count - 1);
221                     
else if (IsRightAlign)
222                         xPos -= extraSpacing * (_rowList.Count -
1);
223                 }
224             }
225             
226             
for (var j = 0; j < _rowList.Count; j++) {
227                 
228                 
var index = IsLowerAlign ? _rowList.Count - 1 - j : j;
229                 
230                 
var rowChild = _rowList[index];
231                 
232                 
var rowChildWidth = LayoutUtility.GetPreferredSize(rowChild, 0) + extraWidth;
233                 
var rowChildHeight = LayoutUtility.GetPreferredSize(rowChild, 1);
234                 
235                 
if (ChildForceExpandHeight)
236                     rowChildHeight = rowHeight;
237                 
238                 rowChildWidth = Mathf.Min(rowChildWidth, maxWidth);
239                 
240                 
var yPos = yOffset;
241
242                 
if (IsMiddleAlign)
243                     yPos += (rowHeight - rowChildHeight) *
0.5f;
244                 
else if (IsLowerAlign)
245                     yPos += (rowHeight - rowChildHeight);
246
247                 
//
248                 
if (ExpandHorizontalSpacing && j > 0)
249                     xPos += extraSpacing;
250
251                 
if (axis == 0)
252                     SetChildAlongAxis(rowChild,
0, xPos, rowChildWidth);
253                 
else
254                     SetChildAlongAxis(rowChild,
1, yPos, rowChildHeight);
255
256                 
// Don't do horizontal spacing for the last one
257                 
if (j < _rowList.Count - 1 )
258                     xPos += rowChildWidth + SpacingX;
259             }
260         }
261         
262         
public float GetGreatestMinimumChildWidth()
263         {
264             
var max = 0f;
265             
266             
for (var i = 0; i < rectChildren.Count; i++) {
267                 
var w = LayoutUtility.GetMinWidth(rectChildren[i]);
268                 
269                 max = Mathf.Max(w, max);
270             }
271             
272             
return max;
273         }
274     }
275 }


Credit Simie

Sourced from - http:forum.unity3d.comthreadsflowlayoutgroup.296709

Example http:forum.unity3d.comthreadsflowlayoutgroup.296709

Update by Martin Sharkbomb - http:forum.unity3d.comthreadsflowlayoutgroup.296709#post-1977028

Last item alignment fix by Vicente Russo - https:bitbucket.orgddreaperunity-ui-extensionsissues22flow-layout-group-align

Layout Group controller that arranges children in rows, fitting as many on a line until total width exceeds parent bounds

Holds the rects that will make up the current row being processed

Main layout method

Width to calculate the layout with

0 for horizontal axis, 1 for vertical

If true, sets the layout input for the axis. If false, sets child position for axis

Width that is available after padding is subtracted

Accumulates the total height of the rows, including spacing and padding.

LowerAlign works from back to front

Max child width is layout group width - padding

If adding this element would exceed the bounds of the row,

go to a new line after processing the current row

Process current row elements positioning

Clear existing row

Add the current row height to total height accumulator, and reset to 0 for the next row

We need the largest element height to determine the starting position of the next line

Don't do this for the last one

Layout the final row

Add the last rows height to the height accumulator

Don't do horizontal spacing for the last one




Trò chơi đua xe động vật trong UNITY Engine 114.841 lượt xem

Gõ tìm kiếm nhanh...